"""
ResumeMyWay
An app which allows you to create an online personal professional journal and 
easily generate different versions of your resume for different purposes.

Copyright (c) 2011 Jay Baxter, Saher Ahwal, Wesam Manassra, Arun Saigal
"""

# TODO: switch to MySQL
import sqlite3


import string
import time

from flask import Flask, render_template, redirect, g, jsonify, request, url_for, session, flash, abort
from contextlib import closing
from flaskext.sqlalchemy import *
#sqlalchemy = __import__("flaskext.sqlalchemy")
#SQLAlchemy = 
#import flaskext
#from flaskext import sqlalchemy


DEBUG = True



DATABASE = 'sqlite:///resumemyway.db'
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE
db = SQLAlchemy(app)

# these imports must follow the assignment to db, since the model classes extend db.Model
from models.GeneratedResume import GeneratedResume
from models.Item import Item
from models.Profile import Profile
#from models.Selection import Selection
from models.User import User
      
# app.config.from_object(__name__)
# used to encrypt cookies
# TODO: key is not actually secret yet
app.secret_key = "\xeb5\x97fI\x05\xd813\xa5\xf5\xd4}\x15\xb8Cfo\xd4['\x194\x11"

# adapted from http://flask.pocoo.org/snippets/8/
from functools import wraps
def access_denied():
    """Function called when access to page is denied. Redirects to login with 
    flash message explaining that login is needed, and saves return page URL
    in query string"""
    flash('To access that page, please log in first')
    # redirect to login, but pass on current path as query string
    # so that returns to previous page after login succeeds
    return redirect(url_for('login', next = request.path))

def requires_login(f):
    """Decorator to be applied to actions that require login."""
    @wraps(f)
    def decorated(*args, **kwargs):
        if not isLoggedIn():
          return access_denied()
        return f(*args, **kwargs)
    return decorated

def get_user_id ():
    """Helper function: if session state has user logged in, return user id, else return None"""
    if 'user_id' in session:
        return session['user_id']
    else:
        return None
    
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/users/new', methods=['GET'])
def new_user():
    """Show form for user registration."""
    return render_template('new_user.html', error=None)

@app.route('/users', methods=['POST'])
def create_user():
    """Register new user."""
    error = None
    u = User.get_by_email(request.form['email'])
    if u is not None:
        error = 'User with that email already exists'
    else:
        u = User(request.form)
        db.session.add(u)
        db.session.commit()
        loginUser(u)
        return redirect(url_for('index'))
    return render_template('login.html', error=error)

@app.route('/login', methods=['GET','POST'])
def login():
    """Handles login. If query string contains url with key 'next', redirected there if login succeeds."""
    error = None
    next_url = request.args['next'] if 'next' in request.args else None
    if request.method == 'POST':
        u = User.get_by_email(request.form['email'])
        if u is not None and u.password == request.form['password']:
            loginUser(u)
            flash('Welcome back, ' + u.first)
            if next_url is not None:
                return redirect(next_url)
            else:
                return redirect(url_for('index'))
        else:
            error = 'Invalid email or password'
    # construct url for form to post to that passes on the return page url
    action_url = url_for('login', next=next_url)
    return render_template('login.html', action_url=action_url, error=error)

@app.route('/logout')
@requires_login
def logout():
    """Handles logout. Field 'logged_in' of session is dropped, by field 'user_id' is left."""
    session.pop('logged_in', None)
    flash('Goodbye, ' + session['first'])
    return redirect(url_for('index'))

def loginUser(user):
    """Login user"""
    session['first'] = user.first
    session['user_id'] = user.id
    session['logged_in'] = True
    
def isLoggedIn():
    """Return whether anybody is logged in"""
    return ('logged_in' in session)

#
#
"""TODO: make AJAXy, tabbed UI, fix URLs?"""
#
#

@app.route('/dashboard')
@requires_login
def dashboard():
    """User's personalized homepage once logged in. Should display the tabbed view."""
    return render_template('dashboard.html')

@app.route('/information')
@requires_login
def information():
    """Returns user's personal information box."""
    return render_template('information.html')

@app.route('/preview')
@requires_login
def preview():
    """Returns the preview page."""
    return render_template('preview.html')

@app.route('/editprofile')
@requires_login
def editprofile():
    """Returns the edit profile page."""
    return render_template('editprofile.html')

@app.route('/account')
@requires_login
def account():
    """Returns the account page."""
    return render_template('account.html')

@app.route('/profiles/new', methods=['GET'])
@requires_login
def new_profile():
    """Show the form for profile creation."""
    pass

@app.route('/profiles', methods=['POST'])
@requires_login
def create_profile():
    """Create a new profile."""
    pass

@app.route('/profiles/<pid>/edit')
@requires_login
def edit_profile():
    """Edit an existing profile."""
    pass

@app.route('/profiles/<pid>/preview')
@requires_login
def preview_profile():
    """Preview an existing profile."""
    pass

@app.route('/profiles/<pid>/delete')
@requires_login
def delete_profile():
    """Delete an existing profile."""
    pass

@app.route('/profiles/<pid>/resumes/get')
@requires_login
def get_resumes():
    """Return a JSON list of generated resumes associated with this profile."""
    pass

@app.route('/profiles/<pid>/resumes/new', methods=['GET'])
@requires_login
def new_resume():
    """Show the form to generate a new resume - do we need this?
    Should we use this URL to actually generate the new resume?"""
    pass

@app.route('/profiles/<pid>/resumes/', methods=['POST'])
@requires_login
def generate_resume():
    """Generate and save a new resume."""
    pass

def get_category_suggestions():
    """For autocompletion.
    Takes the string value associated with the key 'term' in the request
    and returns a JSON object with field 'suggestions'
    that contains an array of strings corresponding to category names
    in the database that include the term as a substring."""
    term = request.args['term']
    matches = Category.get_matching_names(term)    
    return jsonify(suggestions = matches)

@app.route('/get_subject_suggestions')
def get_subject_suggestions():
    """For autocompletion.
    Takes the string value associated with the key 'term' in the request
    and returns a JSON object with field 'suggestions'
    that contains an array of strings corresponding to subject names
    in the database that include the term as a substring."""
    term = request.args['term']
    matches = Subject.get_matching_names(term)    
    return jsonify(suggestions = matches)